home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / vol6n15.arc / DOSKEY.ASM < prev    next >
Assembly Source File  |  1987-07-01  |  35KB  |  749 lines

  1. ;DOSKEY.COM for the IBM Personal Computer - 1987 by Jeff Prosise
  2. ;
  3. bios_data     segment at 40h                ;BIOS Data Area
  4.               org 17h                       ;shift status byte
  5. shft_stat     db ?
  6.               org 84h
  7. crt_rows      db ?                          ;number of display rows
  8.               org 87h
  9. ega_info      db ?                          ;EGA info byte
  10. bios_data     ends
  11. ;
  12. code          segment para public 'code'
  13.               assume cs:code
  14.               org 100h
  15. begin:        jmp initialize
  16. ;
  17. copyright          db 'Copyright 1987 Ziff-Davis Publishing Co.'
  18. author             db 'Jeff Prosise'
  19. ;
  20. cls_text           db 'CLS',13              ;text of clear screen command
  21. stackptr           dw 0                     ;primary command stack pointer
  22. locptr             dw ?                     ;secondary command stack pointer
  23. zcount             db ?                     ;stack pointer relative to zero
  24. ega_flag           db 0                     ;0=no EGA, 1=EGA installed
  25. insert_flag        db 0                     ;status of insert state
  26. foreground         db 7                     ;current foreground color
  27. background         db 0                     ;current background color
  28. dos_segment        dw ?                     ;DOS input buffer segment
  29. columns            db ?                     ;max display column number
  30. bufferptr          db ?                     ;buffer index
  31. ;
  32. ftext              db 4,'dir ',27 dup (0)        ;command linked to F3 key
  33.                    db 5,'type ',26 dup (0)       ;command linked to F4 key
  34.                    db 5,'copy ',26 dup (0)       ;command linked to F5 key
  35.                    db 4,'del ',27 dup (0)        ;command linked to F6 key
  36.                    db 6,'chdir ',25 dup (0)      ;command linked to F7 key
  37.                    db 5,'path ',26 dup (0)       ;command linked to F8 key
  38.                    db 7,'browse ',24 dup (0)     ;command linked to F9 key
  39.                    db 3,'cls',255,27 dup (0)     ;command linked to F10 key
  40.                    db 7,'backup ',24 dup (0)     ;command linked to F11 key
  41.                    db 8,'restore ',23 dup (0)    ;command linked to F12 key
  42. ;
  43. dos_int            label dword
  44. old21h             dw 2 dup (?)             ;interrupt 21h vector
  45. old_int_16        dd 0                     ; old vector
  46. ;
  47. ;------------------------------------------------------------------------------
  48. ;DOSINT routine intercepts calls to interrupt 21h.
  49. ;------------------------------------------------------------------------------
  50. dosint        proc near
  51. ;
  52. ;See if this is a request for DOS function 0Ah.
  53. ;
  54.               sti                           ;restore interrupts
  55.               cmp ah,0Ah                    ;function 0Ah?
  56.               je dos1                       ;yes, then continue
  57. dos_exit:     jmp dos_int                   ;no, then exit to DOS routine
  58. dos1:         cmp dos_segment,0             ;has entry occurred before?
  59.               jne dos3                      ;yes, then branch
  60. ;
  61. ;Initialize command stack and record DS value if this is the first call.
  62. ;
  63.               mov dos_segment,ds            ;record DOS data segment
  64.               push cx                       ;save CX and SI
  65.               push si
  66.               mov cx,20                     ;initialize command stack area
  67.               mov si,offset initialize
  68. dos2:         mov byte ptr cs:[si],0
  69.               add si,128
  70.               loop dos2
  71.               pop si                        ;restore registers
  72.               pop cx
  73. ;
  74. ;See if the function call came from DOS.
  75. ;
  76. dos3:         push bx                       ;save BX register
  77.               mov bx,ds                     ;get DS in BX for compare
  78.               cmp bx,dos_segment            ;call generated from command line?
  79.               pop bx                        ;clean up the stack
  80.               jne dos_exit                  ;no, then exit
  81. ;
  82. ;Get a command line entry from the standard input device.
  83. ;
  84.               push ax                       ;save all registers to be used
  85.               push bx
  86.               push cx
  87.               push dx
  88.               push si
  89.               push di
  90.               push ds
  91.               push es
  92.               push dx                       ;resave buffer offset
  93.               call input                    ;read an input string
  94. ;
  95. ;Copy the entry into the command stack.
  96. ;
  97.               pop dx                        ;recover buffer offset
  98.               mov si,dx                     ;point SI to input buffer
  99.               mov al,[si+1]                 ;get length of input string
  100.               or al,al                      ;is the length zero?
  101.               je dos6                       ;yes, then exit now
  102.               inc si                        ;advance SI to count byte
  103.               push cs                       ;point ES to command stack segment
  104.               pop es
  105.               mov di,stackptr               ;get command stack pointer
  106.               mov cl,7                      ;convert it to an offset address
  107.               shl di,cl
  108.               add di,offset initialize
  109.               mov cl,al                     ;transfer string length to CL
  110.               inc cl                        ;increment to include count byte
  111.               xor ch,ch                     ;byte to word in CX
  112.               cld                           ;clear DF
  113.               rep movsb                     ;copy string to command stack
  114.               inc stackptr                  ;update pointer
  115.               cmp stackptr,15               ;wrap around if necessary
  116.               jne dos4
  117.               mov stackptr,0
  118. dos4:         mov ax,stackptr               ;set LOCPTR = STACKPTR
  119.               mov locptr,ax
  120.               mov zcount,0                  ;initialize base zero pointer
  121. ;
  122. ;See if the command just entered was CLS.
  123. ;
  124.               mov si,dx                     ;point DS:SI to new string
  125.               add si,2
  126.               mov di,offset cls_text        ;and ES:DI to 'CLS' text
  127.               mov cx,4                      ;four bytes to check
  128. dos5:         lodsb                         ;get one byte
  129.               and al,0DFh                   ;capitalize character
  130.               scasb                         ;do the bytes match?
  131.               jne dos6                      ;no, then CLS wasn't entered
  132.               loop dos5                     ;yes, then check another byte
  133.               call clear_screen             ;clear the screen
  134.               sub si,5                      ;reset SI to count byte
  135.               mov [si],0D00h                ;clear string from DOS buffer
  136. ;
  137. ;Restore registers and exit.
  138. ;
  139. dos6:         pop es                        ;restore registers and exit
  140.               pop ds
  141.               pop di
  142.               pop si
  143.               pop dx
  144.               pop cx
  145.               pop bx
  146.               pop ax
  147.               iret
  148. dosint        endp
  149. ;
  150. ;------------------------------------------------------------------------------
  151. ;INPUT reads an input string from the standard input device.
  152. ;------------------------------------------------------------------------------
  153. input         proc near
  154. ;
  155. ;Record video information and initialize parameters.
  156. ;
  157.               mov ah,15                     ;get video page and columns
  158.               int 10h
  159.               dec ah                        ;calculate max column number
  160.               mov columns,ah                ;save it
  161.               push ds                       ;point ES:DI to buffer
  162.               pop es
  163.               mov di,dx
  164.               add di,2
  165.               mov si,dx                     ;point DS:SI to character count
  166.               inc si
  167.               mov byte ptr [si],0           ;zero initial count
  168.               mov bufferptr,1               ;set initial index value
  169.               cld                           ;clear DF
  170. ;
  171. ;Wait for a keycode to appear in the keyboard buffer.
  172. ;
  173. getkey:       mov ah,0Bh                    ;check keyboard buffer for keycode
  174.               int 21h
  175.               or al,al                      ;anything there?
  176.               jne getchar                   ;yes, then go get it
  177.               int 28h                       ;no, then execute interrupt 28h
  178.               jmp getkey                    ;loop back for another try
  179. ;
  180. ;Read the keycode and process it if it's not an extended code.
  181. ;
  182. getchar:      mov ah,8                      ;read character from buffer
  183.               int 21h
  184.               or al,al                      ;is it an extended code?
  185.               je excode                     ;yes, then branch
  186.               cmp al,8                      ;backspace key?
  187.               jne getc1                     ;no, then branch
  188.               call backspace                ;rub out a character
  189.               jmp getkey                    ;return to loop
  190. getc1:        cmp al,27                     ;ESC key?
  191.               jne getc2                     ;no, then branch
  192.               call clear_line               ;yes, then clear input line
  193.               mov ax,stackptr               ;reset LOCPTR
  194.               mov locptr,ax
  195.               mov zcount,0                  ;reset base zero pointer
  196.               jmp getkey
  197. getc2:        cmp al,13                     ;ENTER key?
  198.               je enter                      ;yes, then branch
  199.               call printchar                ;no, then print the character
  200.               jmp getkey
  201. enter:        call eol                      ;place cursor at end-of-line
  202.               mov byte ptr es:[di],13       ;insert carriage return code
  203.               mov ah,2                      ;advance to next line
  204.               mov dl,13
  205.               int 21h
  206.               ret
  207. ;
  208. ;Read the extended code and see if one of the keys F3 thru F12 was pressed.
  209. ;
  210. excode:       mov ah,8                      ;get extended code
  211.               int 21h
  212.               cmp al,133                    ;F11?
  213.               je fkey
  214.               cmp al,134                    ;F12?
  215.               je fkey
  216.               cmp al,61                     ;less than F3?
  217.               jb ex1                        ;yes, then not F3-F10
  218.               cmp al,68                     ;greater tah 68?
  219.               ja ex1                        ;yes, then not F3-F10
  220. fkey:         test al,80h                   ;high bit set (F11 or F12)?
  221.               jz fkey1                      ;no, then branch
  222.               sub al,64                     ;adjust extended code
  223. fkey1:        sub al,61                     ;normalize extended code
  224.               cbw                           ;convert byte to word
  225.               mov cl,5                      ;multiply by 32
  226.               shl ax,cl
  227.               add ax,offset ftext           ;calculate string address
  228.               call write_command            ;output command
  229.               cmp al,255                    ;AL 255 on return?
  230.               je enter                      ;yes, then send entry to DOS
  231.               jmp getkey                    ;return to input loop
  232. ;
  233. ;See if F1 or F2 (or either of the two shifted) was pressed.
  234. ;
  235. ex1:          cmp al,59                     ;F1?
  236.               jne ex2
  237.               inc foreground                ;rotate foreground color forward
  238.               cmp foreground,10h            ;wrap around if necessary
  239.               jne clear
  240.               mov foreground,0
  241.               jmp clear                     ;jump to clear screen routine
  242. ex2:          cmp al,84                     ;Shift-F1?
  243.               jne ex3
  244.               dec foreground                ;decrement foreground color
  245.               cmp foreground,0FFh           ;wrap around if necessary
  246.               jne clear
  247.               mov foreground,0Fh
  248.               jmp clear
  249. ex3:          cmp al,60                     ;F2 key?
  250.               jne ex4
  251.               inc background                ;rotate background color forward
  252.               cmp background,8              ;wrap around if necesaary
  253.               jne clear
  254.               mov background,0
  255.               jmp clear
  256. ex4:          cmp al,85                     ;Shift-F2?
  257.               jne ex5
  258.               dec background                ;decrement background color
  259.               cmp background,0FFh           ;wrap around if necessary
  260.               jne clear
  261.               mov background,7
  262. clear:        call clear_screen             ;clear screen and home cursor
  263.               mov [si],0D00h                ;clear input buffer
  264.               ret
  265. ;
  266. ;See if either Home or End was pressed.
  267. ;
  268. ex5:          cmp al,71                     ;Home?
  269.               jne ex6
  270.               call home                     ;home the cursor
  271.               mov bufferptr,1               ;reset pointers
  272.               mov di,si
  273.               inc di
  274.               jmp getkey
  275. ex6:          cmp al,79                     ;End?
  276.               jne ex7
  277.               call eol                      ;move cursor to end-of-line
  278.               jmp getkey
  279. ;
  280. ;See if either the left or right-arrow key was pressed.
  281. ;
  282. ex7:          cmp al,75                     ;Cursor-Left?
  283.               jne ex8
  284.               call move_left                ;move left one space
  285.               jmp getkey
  286. ex8:          cmp al,77                     ;Cursor-Right?
  287.               jne ex9
  288.               call move_right               ;move right one space
  289.               jmp getkey
  290. ;
  291. ;See if either INS or DEL was pressed.
  292. ;
  293. ex9:          cmp al,82                     ;INS?
  294.               jne ex10
  295.               xor insert_flag,1             ;toggle insert flag
  296.               jmp getkey
  297. ex10:         cmp al,83                     ;DEL?
  298.               jne ex11
  299.               call delete                   ;delete character at cursor
  300.               jmp getkey
  301. ;
  302. ;Output the last command in the stack if Cursor-Up was pressed.
  303. ;
  304. ex11:         cmp al,72                     ;Up?
  305.               jne ex12
  306.               cmp zcount,15                 ;at upper limit of stack?
  307.               je up_exit                    ;yes, then ignore keypress
  308.               mov ax,locptr                 ;get current stack index
  309.               dec ax                        ;move back one command
  310.               cmp ax,0FFFFh                 ;wrap around if necessary
  311.               jne up1
  312.               mov ax,14
  313. up1:          mov dx,ax                     ;save AX in DX
  314.               mov cl,7                      ;calculate address of command
  315.               shl ax,cl
  316.               add ax,offset initialize
  317.               push si                       ;save SI
  318.               mov si,ax                     ;transfer address to SI
  319.               cmp byte ptr cs:[si],0        ;is there a valid command there?
  320.               pop si                        ;restore SI
  321.               je up_exit                    ;no, then ignore keypress
  322.               mov locptr,dx                 ;set LOCPTR
  323.               inc zcount                    ;increment base zero pointer
  324.               call write_command            ;output the command string
  325. up_exit:      jmp getkey
  326. ;
  327. ;Output the next command in the stack if Cursor-Down was pressed.
  328. ;
  329. ex12:         cmp al,80                     ;Down?
  330.               jne ex13
  331.               cmp zcount,0                  ;at head of command stack?
  332.               je ex13                       ;yes, then ignore keypress
  333.               mov ax,locptr                 ;get current stack index
  334.               inc ax                        ;advance one command
  335.               cmp ax,15                     ;wrap around if necessary
  336.               jne dn1
  337.               xor ax,ax
  338. dn1:          mov locptr,ax                 ;set LOCPTR
  339.               dec zcount                    ;decrement base zero pointer
  340.               jnz dn2                       ;branch if not at head of stack
  341.               call clear_line               ;clear command line
  342.               jmp getkey                    ;return to input loop
  343. dn2:          mov cl,7                      ;calculate address of command
  344.               shl ax,cl
  345.               add ax,offset initialize
  346.               call write_command            ;output the command string
  347. ex13:         jmp getkey
  348. input         endp
  349. ;
  350. ;------------------------------------------------------------------------------
  351. ;PRINT_STRING writes an ASCII string to the command line.
  352. ;Entry:  DS:SI - string address
  353. ;        CX    - number of characters
  354. ;------------------------------------------------------------------------------
  355. print_string  proc near
  356.               jcxz ps_exit                  ;exit if no characters
  357.               mov ah,2                      ;DOS function 2 - output char
  358. ps1:          lodsb                         ;get a byte
  359.               mov dl,al                     ;transfer it to DL
  360.               int 21h                       ;output character
  361.               loop ps1                      ;loop until done
  362. ps_exit:      ret
  363. print_string  endp
  364. ;
  365. ;------------------------------------------------------------------------------
  366. ;WRITE_COMMAND outputs a command string.
  367. ;Entry:  AX - string offset address    | Exit:  AL - character after string
  368. ;------------------------------------------------------------------------------
  369. write_command proc near
  370.               push ax                       ;save address
  371.               call clear_line               ;clear input line
  372.               pop ax                        ;retrieve string address
  373.               push ds                       ;save DS and SI
  374.               push si
  375.               push cs                       ;point DS to string segment
  376.               pop ds
  377.               mov si,ax                     ;point SI to the string
  378.               mov cl,[si]                   ;get string length
  379.               xor ch,ch
  380.               mov byte ptr es:[di-1],cl     ;store string length
  381.               inc si                        ;advance SI to string text
  382. write1:       mov ah,2                      ;print one character
  383.               mov dl,[si]
  384.               int 21h
  385.               movsb                         ;transfer character to buffer
  386.               inc bufferptr                 ;advance pointer
  387.               loop write1                   ;loop until done
  388.               lodsb                         ;get first character after string
  389.               pop si                        ;restore registers
  390.               pop ds
  391.               ret
  392. write_command endp
  393. ;
  394. ;------------------------------------------------------------------------------
  395. ;BACKSPACE deletes the character left of the cursor.
  396. ;------------------------------------------------------------------------------
  397. backspace     proc near
  398.               cmp bufferptr,1               ;at beginning of command line?
  399.               je bs_exit                    ;yes, then ignore it
  400.               mov cl,[si]                   ;get count
  401.               sub cl,bufferptr              ;calculate distance to end-of-line
  402.               inc cl
  403.               xor ch,ch
  404.               push cx                       ;save it
  405.               jcxz bs1                      ;branch if at end-of-line
  406. ;
  407. ;Shift all characters right of the cursor in the buffer one slot left.
  408. ;
  409.               push si                       ;save SI and DI
  410.               push di
  411.               mov si,di                     ;position them for shifts
  412.               dec di
  413.               rep movsb                     ;shift characters right of cursor
  414.               pop di                        ;restore registers
  415.               pop si
  416. ;
  417. ;Display the new string and update input parameters.
  418. ;
  419. bs1:          call move_left                ;move cursor left
  420. bs2:          pop cx                        ;retrieve shift count
  421.               push dx                       ;save cursor position
  422.               push si                       ;save SI
  423.               mov si,di                     ;point SI to new part of string
  424.               call print_string             ;print the new part
  425.               mov ah,2                      ;blank the last character
  426.               mov dl,32
  427.               int 21h
  428.               pop si                        ;restore registers
  429.               pop dx                        ;restore cursor address
  430.               mov ah,2                      ;reset the cursor
  431.               int 10h
  432.               dec byte ptr [si]             ;decrement character count
  433. bs_exit:      ret
  434. backspace     endp
  435. ;
  436. ;------------------------------------------------------------------------------
  437. ;PRINTCHAR writes a new character to the input buffer and echoes it.
  438. ;------------------------------------------------------------------------------
  439. printchar     proc near
  440.               cmp insert_flag,0             ;insert state on?
  441.               jne print3                    ;yes, then branch
  442. ;
  443. ;Print a character in overstrike mode.
  444. ;
  445.               mov cl,[si]                   ;get count
  446.               cmp cl,bufferptr              ;end-of-line?
  447.               jae print2                    ;no, then branch
  448.               mov cl,[si-1]                 ;get maximum length
  449.               sub cl,[si]                   ;subtract current length
  450.               cmp cl,1                      ;buffer full?
  451.               je beep                       ;yes, then branch
  452. print1:       inc byte ptr [si]             ;increment count
  453. print2:       stosb                         ;deposit new character
  454.               mov ah,2                      ;then print it
  455.               mov dl,al
  456.               int 21h
  457.               inc bufferptr                 ;advance buffer pointer
  458.               ret
  459. beep:         mov ax,0E07h                  ;print ASCII 7 thru BIOS
  460.               int 10h
  461.               ret
  462. ;
  463. ;Print a character in insert mode.
  464. ;
  465. print3:       mov cl,[si-1]                 ;get maximum length
  466.               sub cl,[si]                   ;subtract current count
  467.               cmp cl,1                      ;buffer full?
  468.               je beep                       ;yes, then branch
  469.               mov cl,[si]                   ;get count
  470.               cmp cl,bufferptr              ;end-of-line?
  471.               jb print1                     ;yes, then branch
  472.               sub cl,bufferptr              ;calculate number of shifts
  473.               inc cl
  474.               xor ch,ch
  475.               push cx                       ;save shift count
  476.               push si                       ;save SI
  477.               add di,cx                     ;position DI to end-of-line
  478.               mov si,di                     ;position SI just before it
  479.               dec si
  480.               std                           ;set DF for now
  481.               rep movsb                     ;make room for new character
  482.               cld                           ;clear DF
  483.               pop si                        ;restore SI
  484.               mov es:[di],al                ;deposit new character
  485.               mov ah,3                      ;get cursor position
  486.               int 10h
  487.               pop cx                        ;retrieve shift count
  488.               inc cx                        ;increment it
  489.               push dx                       ;save cursor position
  490.               push si                       ;save SI
  491.               mov si,di                     ;point SI to current location
  492.               call print_string             ;print new part of string
  493.               pop si                        ;restore SI and DX
  494.               pop dx
  495.               mov ah,2                      ;reset cursor position
  496.               int 10h
  497.               inc byte ptr [si]             ;add to character count
  498.               jmp move_right                ;move cursor right
  499. printchar     endp
  500. ;
  501. ;------------------------------------------------------------------------------
  502. ;DELETE deletes the character at the cursor.
  503. ;------------------------------------------------------------------------------
  504. delete        proc near
  505.               mov cl,[si]                   ;get count
  506.               cmp cl,bufferptr              ;end-of-line?
  507.               jb del2                       ;yes, then ignore keypress
  508.               sub cl,bufferptr              ;calculate number of shifts
  509.               xor ch,ch                     ;byte to word in CX
  510.               push cx                       ;save shift count
  511.               jcxz del1                     ;branch if no shifts
  512.               push si                       ;save SI and DI
  513.               push di
  514.               mov si,di                     ;position registers for shift
  515.               inc si
  516.               rep movsb                     ;shift characters right of cursor
  517.               pop di                        ;restore registers
  518.               pop si
  519. del1:         mov ah,3                      ;get cursor position
  520.               int 10h
  521.               jmp bs2                       ;exit through BACKSPACE routine
  522. del2:         ret
  523. delete        endp
  524. ;
  525. ;------------------------------------------------------------------------------
  526. ;MOVE_LEFT moves the cursor one character left.
  527. ;------------------------------------------------------------------------------
  528. move_left     proc near
  529.               cmp bufferptr,1               ;at beginning of line?
  530.               je left3                      ;yes, then ignore keypress
  531.               mov ah,3                      ;get cursor position
  532.               int 10h
  533.               or dl,dl                      ;column 0?
  534.               je left1                      ;yes, then branch
  535.               dec dl                        ;decrement column number
  536.               jmp left2
  537. left1:        mov dl,columns                ;position at end of previous line
  538.               dec dh
  539. left2:        mov ah,2                      ;set new position
  540.               int 10h
  541.               dec di                        ;decrement pointers
  542.               dec bufferptr
  543. left3:        ret
  544. move_left     endp
  545. ;
  546. ;------------------------------------------------------------------------------
  547. ;MOVE_RIGHT moves the cursor one character right.
  548. ;------------------------------------------------------------------------------
  549. move_right    proc near
  550.               mov cl,[si]                   ;get count
  551.               cmp cl,bufferptr              ;end-of-line?
  552.               jb rt3                        ;yes, then ignore keypress
  553.               mov ah,3                      ;get cursor position
  554.               int 10h
  555.               cmp dl,columns                ;at end-of-line?
  556.               je rt1                        ;yes, then branch
  557.               inc dl                        ;increment column number
  558.               jmp rt2
  559. rt1:          xor dl,dl                     ;beginning of next line
  560.               inc dh
  561. rt2:          mov ah,2                      ;position cursor
  562.               int 10h
  563.               inc di                        ;advance pointers
  564.               inc bufferptr
  565. rt3:          ret
  566. move_right    endp
  567. ;
  568. ;------------------------------------------------------------------------------
  569. ;HOME relocates the cursor to the beginning of the command line.
  570. ;------------------------------------------------------------------------------
  571. home          proc near
  572.               mov cl,bufferptr              ;get position pointer
  573.               dec cl                        ;calculate distance from start
  574.               xor ch,ch
  575.               jcxz home_exit                ;exit if already there
  576. home1:        push cx                       ;save count
  577.               call move_left                ;move left one space
  578.               pop cx                        ;retrieve count
  579.               loop home1                    ;loop until done
  580. home_exit:    ret
  581. home          endp
  582. ;
  583. ;------------------------------------------------------------------------------
  584. ;EOL advances the cursor to the end of the command line.
  585. ;------------------------------------------------------------------------------
  586. eol           proc near
  587.               mov cl,[si]                   ;get count
  588.               cmp cl,bufferptr              ;already at end?
  589.               jb eol_exit                   ;yes, then exit
  590.               sub cl,bufferptr              ;calculate distance from end
  591.               inc cl
  592.               xor ch,ch                     ;byte to word in CX
  593. eol1:         push cx                       ;advance right CX times
  594.               call move_right
  595.               pop cx
  596.               loop eol1
  597. eol_exit:     ret
  598. eol           endp
  599. ;
  600. ;------------------------------------------------------------------------------
  601. ;CLEAR_LINE clears the command line.
  602. ;------------------------------------------------------------------------------
  603. clear_line    proc near
  604.               mov cl,[si]                   ;get count
  605.               xor ch,ch
  606.               jcxz cline2                   ;exit if no characters
  607.               push cx                       ;save count
  608.               call home                     ;home the cursor
  609.               mov ah,3                      ;get cursor position
  610.               int 10h
  611.               pop cx                        ;restore CX
  612.               push dx                       ;save cursor address
  613.               mov ah,2                      ;print ASCII spaces
  614.               mov dl,32
  615. cline1:       int 21h
  616.               loop cline1
  617.               mov ah,2                      ;home cursor again
  618.               pop dx
  619.               int 10h
  620.               mov byte ptr [si],0           ;reset parameters
  621.               mov bufferptr,1
  622.               mov di,si
  623.               inc di
  624. cline2:       ret
  625. clear_line    endp
  626.  
  627. ;------------------------------------------------------------------------------
  628. ;CLEAR_SCREEN clears the display to the currently selected colors.
  629. ;------------------------------------------------------------------------------
  630. clear_screen  proc near
  631.               push ds                       ;save DS
  632.               mov ax,bios_data              ;point DS to BIOS Data Area
  633.               mov ds,ax
  634.               assume ds:bios_data
  635.               mov dl,columns                ;set number of columns
  636.               mov dh,25                     ;set number of screen rows
  637.               cmp ega_flag,0                ;is there an EGA installed?
  638.               je clear1                     ;no, then branch
  639.               test ega_info,8               ;is the EGA the active monitor?
  640.               jnz clear1                    ;no, then branch
  641.               mov dh,crt_rows               ;get number of screen rows
  642. clear1:       mov bh,background             ;formulate attribute for clear
  643.               mov cl,4
  644.               shl bh,cl
  645.               or bh,foreground
  646.               mov ax,0600h                  ;video function - scroll screen
  647.               xor cx,cx                     ;designate entire screen
  648.               int 10h                       ;clear the display
  649.               mov ah,15                     ;determine active video page
  650.               int 10h
  651.               mov ah,2                      ;home the cursor
  652.               xor dx,dx
  653.               int 10h
  654.               pop ds                        ;restore DS
  655.               assume ds:nothing
  656.               ret
  657. clear_screen  endp
  658. ;
  659. ;----------------------------------------------------------------------
  660. ;This enhancement for Int 16 is installed only on machines that use it.
  661. ;----------------------------------------------------------------------
  662. int_16        proc    far
  663.        assume  cs:code, ds:nothing, es:nothing, ss:nothing
  664.  
  665.               pushf                         ;save the flags
  666.               sti                           ;allow interrupts
  667.               cmp ah,2                      ;affects only fn 0,1
  668.               jb bios_1
  669. bios_0:
  670.               popf                          ;restore flags
  671.               jmp old_int_16                ;continue on
  672. bios_1:
  673.               or ah,10h                     ;make extended fn
  674.  
  675.               call old_int_16               ;call old handler
  676.               pushf                         ;save flags
  677.  
  678.               cmp al,0e0h                   ;If low byte isn't E0
  679.               jne bios_2                    ; continue normally
  680.  
  681.               or ah,ah                      ;If char(224)
  682.               jz bios_2                     ; continue
  683.               xor al,al                     ;else make normal extended
  684. bios_2:
  685.               popf                          ;restore these flags
  686.               ret 2                         ;discard original ones
  687.  
  688. int_16        endp
  689.  
  690. ;------------------------------------------------------------------------------
  691. ;INITIALIZE leaves DOSKEY resident in memory.
  692. ;------------------------------------------------------------------------------
  693. initialize    proc near
  694.               assume ds:code
  695. ;
  696. ;Determine whether an EGA is installed.
  697. ;
  698.               mov ah,12h                    ;BIOS video function 12h
  699.               mov bl,10h                    ;return EGA info subfunction
  700.               int 10h                       ;get info
  701.               cmp bl,10h                    ;did BL return unchanged?
  702.               je init1                      ;yes, then there's no EGA here
  703.               inc ega_flag                  ;no, then there is an EGA
  704. ;
  705. ;Save and replace interrupt vectors.
  706. ;
  707. init1:
  708.               mov ax,3521h                  ;save and replace int 21h vector
  709.               int 21h
  710.               mov old21h,bx
  711.               mov old21h[2],es
  712.               mov ah,25h
  713.               lea dx,dosint
  714.               int 21h
  715. ;
  716. ; Determine if BIOS supports enhanced keys.
  717. ;
  718.               xor      ax,ax
  719.               mov      es,ax
  720.        assume  es:nothing
  721.               xor      byte ptr es:[417h],80h
  722.               mov      ah,12h
  723.               int      16h
  724.               cmp      al,byte ptr es:[417h]
  725.               jne      no_support
  726.               xor      byte ptr es:[417h],80h
  727.               mov      ah,12h
  728.               int      16h
  729.               cmp      al,byte ptr es:[417h]
  730.               jne      no_support
  731.  
  732.               mov      ax,3516h
  733.               int      21h
  734.               mov      word ptr old_int_16,bx
  735.               mov      word ptr old_int_16[2],es
  736.               mov      ah,25h
  737.               mov      dx,offset int_16
  738.               int      21h
  739. no_support:
  740. ;
  741. ;Terminate but leave interrupt handling code and buffer space resident.
  742. ;
  743.               mov dx,offset initialize+1920 ;point DX to end of reserved area
  744.               int 27h                       ;terminate-but-stay-resident
  745. initialize    endp
  746. ;
  747. code          ends
  748.               end begin
  749.